using KinonekoSoftware.CodariaDB.Documents.Theories;
using KinonekoSoftware.CodariaDB.Documents.Theories.Chikara;
using KinonekoSoftware.Studio.Models.Theories;

namespace KinonekoSoftware.Studio.Pages.Theories
{
    public sealed partial class WorldViewConfigTheoryViewModel : RepositoryGalleryItem
    {
        private readonly TheoryEngine_Vocabulary _theory_vocabulary;
        private readonly TheoryEngine_Element    _theory_element;
        private readonly TheoryEngine_Rarity     _theory_rarity;
        private readonly TheoryEngine_Chikara    _theory_chikara;

        private bool _placement;
        private int  _version_chikara;
        private int  _version_element;
        private int  _version_rarity;
        private int  _version_vocabulary;
        private TheoryObject _to;

        //-------------------------------------------------
        //
        //          Properties
        //
        //-------------------------------------------------
        public WorldViewConfigTheoryViewModel()
        {
            Platform.GetEngine<
                TheoryEngine_Vocabulary,
                TheoryEngine_Element,
                TheoryEngine_Rarity,
                TheoryEngine_Chikara>(out _,
                                      out _theory_vocabulary,
                                      out _theory_element,
                                      out _theory_rarity,
                                      out _theory_chikara);

            Chikara     = new ObservableCollection<Chikara>();
            Vocabularies = new ObservableCollection<Vocabulary>();
            Elements     = new ObservableCollection<TheoryOfElementPresenter>();
            Rarities     = new ObservableCollection<TheoryOfRarityPresenter>();

            OpenNotionCommand    = CreateCommand<object>(DoOpenNotionCommand);
            OpenStoryCommand     = CreateCommand<object>(DoOpenStoryCommand);
            EditTemplatedCommand = CreateCommand<object>(DoEditTemplatedCommand);

            NewElementCommand    = CreateCommand(DoNewElementCommand);
            ResetElementCommand  = CreateCommand(DoResetElementCommand);
            EditElementCommand   = CreateCommand<TheoryOfElementPresenter>(DoEditElementCommand);
            RemoveElementCommand = CreateCommand<TheoryOfElementPresenter>(DoRemoveElementCommand);

            NewChikaraCommand    = CreateCommand(DoNewChikaraCommand);
            ResetChikaraCommand  = CreateCommand(DoResetChikaraCommand);
            EditChikaraCommand   = CreateCommand<Chikara>(DoEditChikaraCommand);
            RemoveChikaraCommand = CreateCommand<Chikara>(DoRemoveChikaraCommand);
            
            NewRarityCommand    = CreateCommand(DoNewRarityCommand);
            ResetRarityCommand  = CreateCommand(DoResetRarityCommand);
            EditRarityCommand   = CreateCommand<TheoryOfRarityPresenter>(DoEditRarityCommand);
            RemoveRarityCommand = CreateCommand<TheoryOfRarityPresenter>(DoRemoveRarityCommand);

            NewVocabularyCommand    = CreateCommand(DoNewVocabularyCommand);
            ResetVocabularyCommand  = CreateCommand(DoResetVocabularyCommand);
            EditVocabularyCommand   = CreateCommand<Vocabulary>(DoEditVocabularyCommand);
            RemoveVocabularyCommand = CreateCommand<Vocabulary>(DoRemoveVocabularyCommand);

            Title = CatalogHelper.GetCatalogName(CatalogList.WorldView_Theory);
        }

        //-------------------------------------------------
        //
        //          Private Methods
        //
        //-------------------------------------------------
        private void Save()
        {
            Xplat.Debug($"正在保存TheoryOfElements，Version:{_theory_element.Version}");
            Xplat.Debug($"正在保存TheoryOfVocabularies属性，Version:{_theory_vocabulary.Version}");
            Xplat.Debug($"正在保存TheoryOfRarity属性，Version:{_theory_rarity.Version}");
        }

        //-------------------------------------------------
        //
        //          Command Handlers
        //
        //-------------------------------------------------
        private void DoOpenNotionCommand(object element)
        {
            if (element is TheoryOfRarityPresenter toRp)
            {
                this.ThisNotion(toRp.TargetObject);
            }
            else if (element is TheoryOfElementPresenter toEp)
            {
                this.ThisNotion(toEp.TargetObject);
            }
            else if (element is Vocabulary vocabulary)
            {
                this.ThisNotion(vocabulary);
            }
        }

        private void DoOpenStoryCommand(object element)
        {
            if (element is TheoryOfRarityPresenter toRp)
            {
                this.ThisStory(toRp.TargetObject);
            }
            else if (element is TheoryOfElementPresenter toEp)
            {
                this.ThisStory(toEp.TargetObject);
            }
            else if (element is Vocabulary vocabulary)
            {
                this.ThisStory(vocabulary);
            }
        }
        
        private void DoEditTemplatedCommand(object element)
        {
            if (element is null)
            {
                return;
            }

            // var context = new PageContext
            // {
            //     Id = element.Id
            // };
            // context.Set(ContextBase.Key_Value, element);
            // Core.GoTo<TemplatedEditorViewVocabulary>(context);

            //
            Save();
        }

        //-------------------------------------------------
        //
        //          Override
        //
        //-------------------------------------------------

        protected override void OnReceive(PageContext context)
        {
            if (context is not null && context.Has(ContextBase.Key_Value))
            {
                _to = context.GetObject<TheoryObject>(ContextBase.Key_Value);
            }
            
            
            base.OnReceive(context);
        }

        protected override void OnStart()
        {
            Elements.AddMany(_theory_element.Collection.Select(x => TheoryOfElementPresenter.Select(x, Placement)), true);
            Rarities.AddMany(_theory_rarity.Collection.Select(TheoryOfRarityPresenter.Select), true);
            Vocabularies.AddMany(_theory_vocabulary.Collection, true);
            Chikara.AddMany(_theory_chikara.Collection, true);

            _version_chikara    = _theory_chikara.Version;
            _version_element    = _theory_element.Version;
            _version_rarity     = _theory_rarity.Version;
            _version_vocabulary = _theory_vocabulary.Version;
            
            base.OnStart();
        }

        protected override void OnResume()
        {
            if (_version_chikara != _theory_chikara.Version)
            {
                Chikara.AddMany(_theory_chikara.Collection, true);
                _version_chikara = _theory_chikara.Version;
            }
            
            if (_version_element != _theory_element.Version)
            {
                Elements.AddMany(_theory_element.Collection.Select(x => TheoryOfElementPresenter.Select(x, Placement)), true);
                _version_element = _theory_element.Version;
            }
            
            if (_version_rarity != _theory_rarity.Version)
            {
                Rarities.AddMany(_theory_rarity.Collection.Select(TheoryOfRarityPresenter.Select), true);
                _version_rarity = _theory_rarity.Version;
            }
            
            if (_version_vocabulary != _theory_vocabulary.Version)
            {
                Vocabularies.AddMany(_theory_vocabulary.Collection, true);
                _version_vocabulary = _theory_vocabulary.Version;
            }
            base.OnResume();
        }


        //-------------------------------------------------
        //
        //          Properties
        //
        //-------------------------------------------------
        public ICommandEX   EditTemplatedCommand { get; }
        public ICommandEX   OpenNotionCommand    { get; }
        public ICommandEX   OpenStoryCommand     { get; }
        public TheoryObject TheoryObject         => _to;
    }
}